import axios from "axios";
import { generateSignStr } from "./utils";

const lock = {
  isLocked: false,
  queue: [],

  // 获取锁
  acquire() {
    return new window.Promise((resolve) => {
      if (!this.isLocked) {
        // 如果锁没有被占用，直接获取锁
        this.isLocked = true;
        resolve();
      } else {
        // 如果锁被占用，将当前请求加入队列中
        this.queue.push(resolve);
      }
    });
  },

  // 释放锁
  release() {
    // 如果队列中有等待请求，调用下一个请求的 resolve 方法
    if (this.queue.length > 0) {
      const nextResolve = this.queue.shift();
      nextResolve();
    } else {
      // 如果队列中没有等待请求，释放锁
      this.isLocked = false;
    }
  },
};

const configFunc = async (config) => {

  try {
    await lock.acquire();
    config.headers["x-android-id"] = window.localStorage.getItem("androidId");
    const token = window.sessionStorage.getItem("token");
    if (token) {
      let nonceArray = window.sessionStorage.getItem("nonceArray").split(",");
      let nonce = nonceArray ? nonceArray.shift() : null;
      if (nonce) {
        config.headers["x-nonce"] = nonce;
        window.sessionStorage.setItem("nonceArray", nonceArray);
      } else {
        if (!IS_DEV) {
          // ignore nonce in DEV ENV if has no any one
          window.Promise.reject("has no nonce");
        }
      }
      config.headers.Authorization = `Bearer ${token}`;
      config.data.sign = generateSignStr(nonce, config.data.sign);
    }
    lock.release();

    return config;
  } catch (error) {
    return window.Promise.reject(error);
  }
};

const respFunc = async (response) => {
  await lock.acquire();

  let nonceArray = window.sessionStorage.getItem("nonceArray");
  if (!nonceArray) {
    nonceArray = [];
  } else {
    nonceArray = nonceArray.split(",");
  }

  let nonce = response.headers["x-nonce"];
  if (nonce) {
    nonceArray.push(nonce);
  }

  window.sessionStorage.setItem("nonceArray", nonceArray);
  lock.release();

  return response;
  
};

const matryoshkaInstance = axios.create({
  timeout: 30000,
});

const dachshundInstance = axios.create({
  timeout: 30000,
});

matryoshkaInstance.interceptors.request.use(configFunc);
matryoshkaInstance.interceptors.response.use(respFunc);

dachshundInstance.interceptors.request.use(configFunc);
dachshundInstance.interceptors.response.use(respFunc, async (error) => {
  await respFunc(error.response);
  throw error;
});

export default {
  matryoshkaInstance,
  dachshundInstance,
};
